# [Java]多线程 ## 创建 - 使用Thread类开发多线程程序的步骤: 1. 自定义一个子类,继承Thread 2. 在子类中,重写run()方法(run方法中书写的是线程要执行的任务代码) **Thread类中包含了创建并执行多线程的功能方法+线程要执行的任务(耦合度过高)** 3. 创建一个子类对象 4. 通过子类对象调用.start() 开启一个新线程并执行 - 使用Runnable接口开发多线程的步骤: 1. 自定义一个实现Runnable接口的子类 2. 在子类重写run方法 3. 创建一个子类对象,并把该对象作为参数传递给Thread对象 4. 创建一个Thread对象,并把实现Runnable接口的子类对象作为参数 5. 调用Thread对象中的start方法 - 使用Runnable接口比Thread类的优点: - 适合多个程序实现共享同一份资源 - 实现了解耦 - 避免Java中的单继承 - 实现Callable接口来创建线程: 1. 自定义一个子类实现Callable 2. 在子类中重写call方法 3. 创建线程池 4. 创建Callable子类对象 5. 把Callable对象作为参数传递给线程池 ## 线程安全 - 发生原因: - 安全问题都是由全局变量及静态变量造成的 - **多个线程同时对一个共享数据进行访问(在访问的同时存在修改操作)**,由于CPU切换不同的线程可能存在: A线程进行了修改,B线程却使用了修改前的数据 - 解决方案: - 本质:把多线程变成单线程 - 引入**线程同步**机制 - 同步代码块 - 针对run方法中的代码,使用synchronized关键字,把部分代码添加同步机制 - 同步机制:在同一个而时间,只能有一个线程执行 - 原理:线程在执行之前先获取到一个锁,然后开始执行线程任务,只有拿到锁的线程执行完包含在synchronized代码块中的内容之后,才会释放锁,才可以让其他线程拿到这个锁 - 同步机制,关键是实现利用:锁(对象锁) - 锁: 对象锁。任何对象都可以当锁使用 - String lock = new String() - Object lock = new Object() - 同步方法 - 针对方法进行同步,同步方法只能用在方法上 - 格式:public synchronized void method(){...} - 同步方法中的锁: - 非静态方法:锁是this(锁,当前对象) - 静态方法:静态方法没有对象的概念。所示Class(锁,类名.class) - 锁机制 ## 线程的生命周期 从线程的创建开始,一直到线程的销毁,整个过程称为:生命周期 - 划分: - 创建 start() 线程创建成功 - 就绪 - 运行 - 死亡 ## 线程控制 - 控制方法: - sleep() 当前执行的线程进入睡眠状态 - join() 等待当前线程死亡,当前线程必须执行完才能执行其他线程 - setDeamon() 设置当前线程为和守护线程,特点:当没有普通线程在执行时,守护线程也停止运行 ## Loock锁